<template>
    <span class="fm-style">
        <el-container class="fm2-container">
            <el-main class="fm2-main">
                <el-container>
                    <!-- 侧边栏 表单控件 -->
                    <el-aside width="250px">
                      <div class="components-list">
                        <template v-if="basicFields.length">
                          <div class="widget-cate">基础表单</div>
                          <draggable tag="ul" :list="basicComponents"
                            v-bind="{group:{ name:'people', pull:'clone',put:false},sort:false, ghostClass: 'ghost'}"
                            @end="handleMoveEnd"
                            @start="handleMoveStart"
                            :move="handleMove">

                            <li v-if="basicFields.indexOf(item.type)>=0" class="form-edit-widget-label" :class="{'no-put': item.type == 'divider'}" v-for="(item, index) in basicComponents" :key="index">
                              <a>
                                <i class="icon iconfont" :class="item.icon"></i>
                                <span>{{item.name}}</span>
                              </a>
                            </li>
                          </draggable>
                        </template>

                        <template v-if="advanceFields.length">
                          <div class="widget-cate">高级表单</div>
                          <draggable tag="ul" :list="advanceComponents"
                            v-bind="{group:{ name:'people', pull:'clone',put:false},sort:false, ghostClass: 'ghost'}"
                            @end="handleMoveEnd"
                            @start="handleMoveStart"
                            :move="handleMove"
                          >

                            <li v-if="advanceFields.indexOf(item.type) >= 0" class="form-edit-widget-label" :class="{'no-put': item.type == 'table'}" v-for="(item, index) in advanceComponents" :key="index">
                              <a>
                                <i class="icon iconfont" :class="item.icon"></i>
                                <span>{{item.name}}</span>
                              </a>
                            </li>
                          </draggable>
                        </template>


                        <template v-if="layoutFields.length">
                          <div class="widget-cate">{{$t('fm.components.layout.title')}}</div>
                          <draggable tag="ul" :list="layoutComponents"
                            v-bind="{group:{ name:'people', pull:'clone',put:false},sort:false, ghostClass: 'ghost'}"
                            @end="handleMoveEnd"
                            @start="handleMoveStart"
                            :move="handleMove"
                          >

                            <li v-if="layoutFields.indexOf(item.type) >=0" class="form-edit-widget-label no-put" v-for="(item, index) in layoutComponents" :key="index">
                              <a>
                                <i class="icon iconfont" :class="item.icon"></i>
                                <span>{{item.name}}</span>
                              </a>
                            </li>
                          </draggable>
                        </template>

                      </div>

                    </el-aside>

                    <!-- 主画布区域 -->
                    <el-container class="center-container" direction="vertical">
                        <el-header class="btn-bar" style="height: 45px;">
                            <slot name="action">
                                <span class="fm-action-tools">
                                    <el-tooltip v-for="item in models" :key="item.id"  class="item" effect="dark" :content="item.title" placement="bottom">
                                        <i class="icon" :class="{
                                            'icon-pc' : item.icon == 'pc',
                                            'icon-pad' : item.icon == 'pad',
                                            'icon-mobile' : item.icon == 'mobile',
                                            active : item.active
                                          }" @click="setFormWidth(item.width, item.id)"></i>
                                    </el-tooltip>
                                </span>

                                <EditorStep ref="step"></EditorStep>
                            </slot>

                            <el-button v-if="clearable" type="text" size="medium" icon="el-icon-delete" @click="handleClear">{{$t('fm.actions.clear')}}</el-button>
                            <el-button v-if="preview" type="text" size="medium" icon="el-icon-view" @click="handlePreview">{{$t('fm.actions.preview')}}</el-button>
                            <el-button v-if="generateJson" type="text" size="medium" icon="el-icon-tickets" @click="getGenerateJson">保存</el-button>
                            <el-button v-if="generateCode" type="text" size="medium" @click="handleGenerateCode"><i class="btn-icon icon-publish"></i>发布</el-button>
        <!--                    <el-button v-if="generateCode" type="text" size="medium" icon="el-icon-document" @click="handleGenerateCode">{{$t('fm.actions.code')}}</el-button>-->
                        </el-header>

                        <el-main :class="{'widget-empty': widgetForm.list.length == 0}">
                              <widget-form v-if="!resetJson"  ref="widgetForm" :data="widgetForm" :select.sync="widgetFormSelect"></widget-form>
                        </el-main>
                    </el-container>

                    <!-- 右侧控件属性栏 -->
                    <el-aside class="widget-config-container">
                        <el-container>
                          <el-header height="45px">
                            <div class="config-tab" :class="{active: configTab=='widget'}" @click="handleConfigSelect('widget')">{{$t('fm.config.widget.title')}}</div>
                            <div class="config-tab" :class="{active: configTab=='form'}" @click="handleConfigSelect('form')">{{$t('fm.config.form.title')}}</div>
                          </el-header>
                          <el-main class="config-content">
                            <widget-config v-show="configTab=='widget'" :data="widgetFormSelect"></widget-config>
                            <form-config v-show="configTab=='form'" :data="widgetForm.config"></form-config>
                          </el-main>
                      </el-container>

                    </el-aside>

                    <cus-dialog
                      :visible="previewVisible"
                      @on-close="previewVisible = false"
                      ref="widgetPreview"
                      width="1000px"
                      form
                    >
                      <generate-form insite="true" @on-change="handleDataChange" v-if="previewVisible" :data="widgetForm" :value="widgetModels" :remote="remoteFuncs" ref="generateForm">

                        <template v-slot:blank="scope">
                          Width <el-input v-model="scope.model.blank.width" style="width: 100px"></el-input>
                          Height <el-input v-model="scope.model.blank.height" style="width: 100px"></el-input>
                        </template>
                      </generate-form>

                      <template slot="action">
                        <el-button type="primary" @click="handleTest">{{$t('fm.actions.getData')}}</el-button>
                        <el-button @click="handleReset">{{$t('fm.actions.reset')}}</el-button>
                      </template>
                    </cus-dialog>

                    <cus-dialog
                      :visible="uploadVisible"
                      @on-close="uploadVisible = false"
                      @on-submit="handleUploadJson"
                      ref="uploadJson"
                      width="800px"
                      form
                    >
                      <el-alert type="info" :title="$t('fm.description.uploadJsonInfo')"></el-alert>
                      <div id="uploadeditor" style="height: 400px;width: 100%;">{{jsonEg}}</div>
                    </cus-dialog>

                    <cus-dialog
                      :visible="jsonVisible"
                      @on-close="jsonVisible = false"
                      ref="jsonPreview"
                      width="800px"
                      form
                    >

                      <div id="jsoneditor" style="height: 400px;width: 100%;">{{jsonTemplate}}</div>

                      <template slot="action">
                        <el-button type="primary" class="json-btn" :data-clipboard-text="jsonCopyValue">{{$t('fm.actions.copyData')}}</el-button>
                      </template>
                    </cus-dialog>

                    <!-- 预览 -->
                    <cus-dialog
                      :visible="codeVisible"
                      @on-close="codeVisible = false"
                      ref="codePreview"
                      width="800px"
                      form
                      :action="false"
                    >
                      <!-- <div id="codeeditor" style="height: 500px; width: 100%;">{{htmlTemplate}}</div> -->
                      <el-tabs type="border-card" style="box-shadow: none;" v-model="codeActiveName">
                        <el-tab-pane label="Vue Component" name="vue">
                          <div id="vuecodeeditor" style="height: 500px; width: 100%;">{{vueTemplate}}</div>
                        </el-tab-pane>
                        <el-tab-pane label="HTML" name="html">
                          <div id="codeeditor" style="height: 500px; width: 100%;">{{htmlTemplate}}</div>
                        </el-tab-pane>
                      </el-tabs>
                    </cus-dialog>
                </el-container>
            </el-main>

            <el-footer height="30px" style="font-weight: 600;">
                <FormFooter></FormFooter>
            </el-footer>
        </el-container>
    </span>
</template>

<script>
import Draggable from 'vuedraggable'
import WidgetConfig from './WidgetConfig'
import FormConfig from './FormConfig'
import WidgetForm from './WidgetForm'
import CusDialog from './CusDialog'
import GenerateForm from './GenerateForm'
import {basicComponents, layoutComponents, advanceComponents} from './componentsConfig.js'
import request from '../../util/request.js'
import generateCode from './generateCode.js'
import FormFooter from "./FormLayout/FormFooter";
import editor from "../../assets/config/editor";
import date from "../../assets/common/date";
import EditorStep from "./FormLayout/EditorStep";

export default {
    name: 'fm-making-form',
    components: {
        EditorStep,
        FormFooter,
        Draggable,
        WidgetConfig,
        FormConfig,
        WidgetForm,
        CusDialog,
        GenerateForm
    },
    props: {
      preview: {
        type: Boolean,
        default: false
      },
      generateCode: {
        type: Boolean,
        default: false
      },
      generateJson: {
        type: Boolean,
        default: false
      },
      upload: {
        type: Boolean,
        default: false
      },
      clearable: {
        type: Boolean,
        default: false
      },
      basicFields: {
        type: Array,
        default: () => ['input', 'textarea', 'number', 'radio', 'checkbox', 'time', 'date', 'rate', 'color', 'select', 'switch', 'slider']
      },
      advanceFields: {
        type: Array,
        default: () => ['blank', 'imgupload', 'editor', 'cascader']
      },
      layoutFields: {
        type: Array,
        default: () => ['grid']
      }
    },
    data () {
        return {
            models: editor.models,
            basicComponents,
            layoutComponents,
            advanceComponents,
            resetJson: false,
            widgetForm: {
              list: [],
              config : {
                labelWidth: 100,
                labelPosition: 'right',
                size: 'small'
              }
            },
            configTab: 'widget',
            widgetFormSelect: null,
            previewVisible: false,
            jsonVisible: false,
            codeVisible: false,
            uploadVisible: false,
            remoteFuncs: {
              func_test (resolve) {
                setTimeout(() => {
                  const options = [
                    {id: '1', name: '1111'},
                    {id: '2', name: '2222'},
                    {id: '3', name: '3333'}
                  ]

                  resolve(options)
                }, 2000)
              },
              funcGetToken (resolve) {
                request.get('http://tools-server.xiaoyaoji.cn/api/uptoken').then(res => {
                  resolve(res.uptoken)
                })
              },
              upload_callback (response, file, fileList) {
                console.log('callback', response, file, fileList)
              }
            },
            widgetModels: {},
            blank: '',
            htmlTemplate: '',
            vueTemplate: '',
            jsonTemplate: '',
            uploadEditor: null,
            jsonCopyValue: '',
            jsonClipboard: null,
            jsonEg: `{
              "list": [],
              "config": {
                "labelWidth": 100,
                "labelPosition": "top",
                "size": "small"
              }
            }`,
            codeActiveName: 'vue',
            steps: []
        }
    },
    mounted () {
        this._loadComponents();

        this.setJSON(editor.getCurrentData());
    },
    methods: {
        //加载组件
        _loadComponents () {
          this.basicComponents = this.basicComponents.map(item => {
            return {
              ...item,
              name: this.$t(`fm.components.fields.${item.type}`)
            }
          })
          this.advanceComponents = this.advanceComponents.map(item => {
            return {
              ...item,
              name: this.$t(`fm.components.fields.${item.type}`)
            }
          })
          this.layoutComponents = this.layoutComponents.map(item => {
            return {
              ...item,
              name: this.$t(`fm.components.fields.${item.type}`)
            }
          })
        },
        handleConfigSelect (value) {
            this.configTab = value
        },
        //拖动元素图标 结束 事件
        handleMoveEnd (evt) {
            console.log(evt);
            this.$refs.step.setStep(this.widgetForm)
        },
        //拖动左侧元素图标 开始事件
        handleMoveStart ({oldIndex}) {
            console.log('图标拖动开始', oldIndex)
        },
        handleMove () {
            return true
        },
        //预览
        handlePreview () {
            this.previewVisible = true
        },
        handleTest () {
          this.$refs.generateForm.getData().then(data => {
            this.$alert(data, '').catch(e=>{})
            this.$refs.widgetPreview.end()
          }).catch(e => {
            this.$refs.widgetPreview.end()
          })
        },
        handleReset () {
          this.$refs.generateForm.reset()
        },
        getGenerateJson () {
            let data = JSON.stringify(this.widgetForm);
            localStorage.setItem('editor_temp', data);
            this.$message.success('保存成功！');
        },
        handleGenerateCode () {
          this.codeVisible = true
          this.htmlTemplate = generateCode(JSON.stringify(this.widgetForm), 'html')
          this.vueTemplate = generateCode(JSON.stringify(this.widgetForm), 'vue')
          this.$nextTick(() => {
            const editor = ace.edit('codeeditor')
            editor.session.setMode("ace/mode/html")

            const vueeditor = ace.edit('vuecodeeditor')
            vueeditor.session.setMode("ace/mode/html")
          })
        },
        handleUpload () {
            this.uploadVisible = true;
            this.$nextTick(() => {
                this.uploadEditor = ace.edit('uploadeditor')
                this.uploadEditor.session.setMode("ace/mode/json")
            })
        },
        handleUploadJson () {
          try {
            this.setJSON(JSON.parse(this.uploadEditor.getValue()))
            this.uploadVisible = false
          } catch (e) {
            this.$message.error(e.message)
            this.$refs.uploadJson.end()
          }
        },
        handleClear () {
            this.widgetForm = {
                list: [],
                config: {
                  labelWidth: 100,
                  labelPosition: 'right',
                  size: 'small',
                  customClass: ''
                },
            }

          this.widgetFormSelect = {}
        },
        //清空表单
        clear () {
            this.handleClear()
        },
        getHtml () {
          return generateCode(JSON.stringify(this.widgetForm))
        },
        setJSON (json) {
            this.widgetForm = json

            if (json.list.length> 0) {
                this.widgetFormSelect = json.list[0]
            }
        },
        handleInput (val) {
          console.log(val)
          this.blank = val
        },
        handleDataChange (field, value, data) {
            console.log('数据改变！');
            console.log(field, value, data);
        },
        //设置表单宽度
        setFormWidth(width, id){
            let style = { width };

            Object.keys(this.models).forEach( (ids) => {
                this.models[ids].active = false;
            })

            this.models[id].active = true;
            this.$refs.widgetForm.setWidgetWidth(style);
        }
    },
    watch: {
        widgetForm: {
            deep: true,
            handler: function (val) {
                console.log(this.$refs.widgetForm)
                console.log(val);
            }
        },
        '$lang': function (val) {
            this._loadComponents()
        }
    }
}
</script>

<style lang="scss">
    @import "../../assets/iconfont.scss";

    .fm-action-tools{
        float: left;
        height: 42px;
        display: flex;
        justify-content: center;
        justify-items: center;

        >i{
            border-radius: 6px;
            margin: 5px 2px;
            height: 32px;
            width: 32px;
            text-align: center;
            line-height: 32px;

            &.active{
                background: #eeeeee;
                color: #3296FA;
            }
        }
    }

    .widget-form-list{
        min-height: calc(100vh - #{148px}) !important;
        margin: 10px auto !important;
    }
</style>
